#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <stdint.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <stdbool.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <dlfcn.h>
#include <pthread.h>
#include <linux/fb.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include "shmhead.h"

bool ready = true;

void setflag(int sig)
{
    printf("收到信号: %d\n", sig);
    ready = true;
}

void cleanfifo(int sig)
{
    remove(FIFO12);
    remove(FIFO21);
    exit(0);
}

int main(int argc, char const *argv[])
{
    // 注册对方已经读完消息的信号SIGUSR2
    signal(SIGUSR2, setflag);
    signal(SIGINT, cleanfifo);

    // 0，互通双方的PID，以便发信号
    mkfifo(FIFO12, 0666);
    mkfifo(FIFO21, 0666);
    int fifo12 = open(FIFO12, O_RDWR);
    int fifo21 = open(FIFO21, O_RDWR);

    pid_t mypid = getpid();
    write(fifo12, &mypid, sizeof(mypid));
    pid_t peerpid;
    read(fifo21, &peerpid, sizeof(peerpid));

    printf("p1: %d\n", mypid);
    printf("p2: %d\n", peerpid);

    // 1， 创建共享内存IPC
    key_t key = ftok(MSGPATH, PROJID);   
    int shmid = shmget(key, 128, IPC_CREAT|0666);

    // 2，将SHM映射到本进程的内存空间
    //    NULL: 让Linux自动为本SHM分配虚拟地址入口
    //    0   : 以读写方式映射
    char *p = shmat(shmid, NULL, 0);
    if(p == (void*)-1)
    {
        perror("shmat失败");
        exit(0);
    }

    // 3，让SHM放入数据
    while(1)
    {
        if(ready)
        {
            ready = false;
            snprintf(p, 128, "%s", "abcdg\n");
            // 通知对方数据已发送，可以处理了
            kill(peerpid, SIGUSR1);

            int n = rand()%5+1;
            for(int i=n; i>=0; i--)
            {
                fprintf(stderr, "%d\n", i);
                sleep(1);
            }
        }
    }

    return 0;
}
